package com.example.utils;

import lombok.Data;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.joda.time.DateTime;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
/*
* 解析excel表格工具类
* */

public class ReadExcelUtil {

    public static <T> List<T> readExcel(Workbook workbook,FileInputStream inputStream,Class<T> clazz) throws Exception{
        List<T> result = new ArrayList<>();
        //获取目标工作表
        Sheet sheet = workbook.getSheetAt(0);
        //获取目标的行数
        int rowNum = sheet.getPhysicalNumberOfRows();
        //获取第一行
        Row row = sheet.getRow(0);
        //遍历第一行数据
        List<String> key = new ArrayList<>();
        //具体遍历
        for(Cell cell : row){
            if (cell != null){
                //获取单元格数据
                String value= getCellValue(cell);
                key.add(value);
                System.out.println(value);
            }
        }
        //遍历正式数据
        for (int i = 1; i < rowNum; i++){
            row = sheet.getRow(i);
            if (row != null){
                //计数器 j 用于映射数据使用
                int j = 0;
                // 用于保存每条数据的map，并在map建立对应的映射关系
                Map<String,String> excleMap = new HashMap<>();
                for (Cell cell : row){
                    if(cell != null){
                        String value = getCellValue(cell);
                        if(value != null && !value.equals("")){
                            //将每个单元格的数据存储到集合中
                            excleMap.put(key.get(j),value);
                            j++;
                        }
                    }
                }
                T t = mapToEntity(excleMap,clazz);
                result.add(t);
            }
        }
        inputStream.close();

        return result;
    }
    //  去小数点
    public static NumberFormat nf = NumberFormat.getNumberInstance();
    static {
        nf.setGroupingUsed(false);
    }

    //判断类型方法
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell != null) {
            int cellType = cell.getCellType();
            switch (cellType) {
                case XSSFCell.CELL_TYPE_STRING:
                    cellValue = cell.getStringCellValue();
                    break;
                case XSSFCell.CELL_TYPE_BOOLEAN:
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case XSSFCell.CELL_TYPE_BLANK:
                    break;
                case XSSFCell.CELL_TYPE_NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date dateCellValue = cell.getDateCellValue();
                        cellValue = new DateTime(dateCellValue).toString("yyyy-MM-dd");
                    } else {
                        // 不是日期格式，防止数字过长
                        cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                        cellValue = cell.getStringCellValue();
                    }
                    break;
                case XSSFCell.CELL_TYPE_ERROR:
                    break;
            }
        }
        return cellValue;

    }

    private static <T> T mapToEntity(Map<String,String> map,Class<T> entity){
        T t = null;
        try {
            t = entity.newInstance();
            for (Field field : entity.getDeclaredFields()){
                if (map.containsKey(field.getName())){
                    boolean flag = field.isAccessible();
                    field.setAccessible(true);
                    //获取map中属性对应的值
                    String str = map.get(field.getName());
                    //获取map中属性对应的类型
                    String type = field.getGenericType().toString();
                    //判定对应属性的值
                    if (str != null){
                        if(type.equals("class java.lang.String")){
                            field.set(t,str);
                        }
                        else if(type.equals("class java.lang.double")){
                            field.set(t, Double.parseDouble(String.valueOf(str)));
                        }else if(type.equals("class java.lang.Integer")){
                            field.set(t,Integer.parseInt(String.valueOf(str)));
                        }else if (type.equals("class java.lang.util.Date")){
                            Date date = new SimpleDateFormat("yyyy-MM-dd").parse(str);
                            field.set(t,date);
                        }else if (type.equals("class java.time.LocalDate")){
                            field.set(t, LocalDate.parse(str));
                        }
                    }
                    field.setAccessible(flag);
                }
            }
            return t;
        }catch (Exception e){
            e.printStackTrace();
        }
        return t;
    }

}


